/******************************************************************************************
文件名：cmd_process_handle.c
作者：狼狼    版本：V1.0    创建日期：2021.9.9
文件描述：
    内部指令处理回调。
历史修改记录：
1. 2021-9-9:V1.0 狼狼
创建。
2. 2022-5-11:V1.0 狼狼
代码公开。
******************************************************************************************/
//+------------------------------------------------------------------------------------------+
//|                                          文件说明
//+------------------------------------------------------------------------------------------+
//|      [注意]本文件中所有回调必须为非阻塞执行。
//|      [补充]对从内部指令中传递的指向参数的指针，由设计者决定如何读写，因此不提供其长度信息，
//|  当指令执行完成后，要按需释放参数空间，以免造成内存泄漏。
//|      当需要增加指令时，按照以下步骤进行：
//|  1. 在指令记录表中增加对指令的记录项，以接收来自TCP的指令消息；
//|  2. 在本文件中增加指令执行回调函数，并声明到同名头文件中；
//|  3. 更新指令记录表中对应的回调函数记录字段；
//|  4. 实现其它必要的功能。
//+------------------------------------------------------------------------------------------+
//|                                         头文件包含
//+------------------------------------------------------------------------------------------+
/*|*/#include <stdio.h>
/*|*/#include <string.h>
/*|*/#include <stdlib.h>
/*|*/#include <stdint.h>
//|
/*|*/#include "cmd_process_handle.h"
/*|*/#include "loice_slave_parser.h"
/*|*/#include "cmd_reg_table.h"
/*|*/#include "L_GPIO_Peripherals.h"
/*|*/#include "project_debug.h"
//+------------------------------------------------------------------------------------------+
//|                                          全局变量
//+------------------------------------------------------------------------------------------+
//|    ----------------------------------------
//|    指令记录表
//|    [说明]指令记录表用于内部指令注册，解析器
//|          将访问该表以判断指令的合法性；执行
//|          机制将访问该表以执行对应的回调函数。
//|    ----------------------------------------
/*|*/ST_CMD_REG_TABLE cmd_reg_table[] = 
/*|*/{
/*|*/    {CMD_ACTION , 1, cmd_1_1_handle}, // 启动H264-720P编码，仅视频
/*|*/    {CMD_CONTROL, 1, cmd_4_1_handle}, // 停止编码动作
//|
/*|*/    {CMD_RESERVED, 0, NULL} /* 用于判定结尾的记录项 */
/*|*/};
//|
/*|*/extern ST_PARSER *pparser_obj;
/*|*/extern uint32_t pending_session_list[MAX_SESSION_NUM];
/*|*/extern uint16_t pending_session_data_seq_cnt[MAX_SESSION_NUM];
//+------------------------------------------------------------------------------------------+
//|  回调函数名称：cmd_1_1_handle
//|  功能描述：启动H264-720P编码，仅视频
//|  备注：
/*
Command Sample:
14 CF 92 5A A0 C0 00 FF 
00 00 00 00 11 11 11 11 22 22 22 22 33 33 33 33 44 44 44 44 55 55 55 55 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01 00 00 00 
00 00 00 00 00 00 00 00 
08 00 00 00 
01 00 34 08 
01 00 01 00 02 00 00 00
*/
//+------------------------------------------------------------------------------------------+
void cmd_1_1_handle(ST_INTERNAL_CMD internal_cmd)
{
    printf("[CMD_HANDLE][Session ID:%d][Seq:%d]Recv command[ID:%d - Value:%d]\n", internal_cmd.session_id,
                                                                                  internal_cmd.msg_seq,
                                                                                  internal_cmd.cmd_id,
                                                                                  internal_cmd.cmd_value);
    // ----------------------------------------
    // [说明]将会话加入到待发送列表中，H264数据
    //       将按照单包模式逐帧发送，每帧被封为
    //       一包。发送过程中无需考虑IDR帧起始
    //       的问题，接收端可使用流式解码。
    // [注意]在Demo中，对于指令的执行没有过多考
    //       虑，因此忽略掉如消息序列号等的传递。
    // ----------------------------------------
    for(int i = 0; i < MAX_SESSION_NUM; i++)
    {
        if(pending_session_list[i] == 0)
        {
            pending_session_list[i] = internal_cmd.session_id;
            break;
        }
    }
    
    /* 对于含参指令，需要释放参数 */
    if(internal_cmd.pargs)free(internal_cmd.pargs);
}

//+------------------------------------------------------------------------------------------+
//|  回调函数名称：cmd_4_1_handle
//|  功能描述：停止编码动作
//|  备注：
/*
Command Sample:
14 CF 92 5A A0 C0 00 FF 
00 00 00 00 11 11 11 11 22 22 22 22 33 33 33 33 44 44 44 44 55 55 55 55 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01 00 00 00 
00 00 00 00 00 00 00 00 
08 00 00 00 
01 00 34 08 
04 00 01 00 05 00 00 00
*/
//+------------------------------------------------------------------------------------------+
void cmd_4_1_handle(ST_INTERNAL_CMD internal_cmd)
{
    printf("[CMD_HANDLE][Session ID:%d][Seq:%d]Recv command[ID:%d - Value:%d]\n", internal_cmd.session_id,
                                                                                  internal_cmd.msg_seq,
                                                                                  internal_cmd.cmd_id,
                                                                                  internal_cmd.cmd_value);
    /* 查找会话位置 & 从解析器中删除会话 */
    for(int i = 0;i < MAX_SESSION_NUM; i++)
    {
        if(pending_session_list[i] == internal_cmd.session_id)
        {
            pending_session_list[i] = 0;
            pending_session_data_seq_cnt[i] = 0;
        }
    }
    
    /* 清除会话忙标志位 */
    pparser_obj->clear_cmd_action_flag(pparser_obj, internal_cmd.session_id);
    
    /* 对于含参指令，需要释放参数 */
    if(internal_cmd.pargs)free(internal_cmd.pargs);
}
